/*
 * TcpTsMediaCaster.cpp
 *
 *  Created on: 2019年2月28日
 *      Author: terry
 */

#include "TcpTsMediaCaster.h"
#include "TcpMediaCasterConnection.h"


namespace av
{

TcpTsMediaCaster::TcpTsMediaCaster()
{
}

TcpTsMediaCaster::~TcpTsMediaCaster()
{
    close();
}

int TcpTsMediaCaster::open(const std::string& ip, uint16_t port, const MediaFormat& fmt)
{
    if (!TcpServer::start(ip.c_str(), port))
    {
        return ENOENT;
    }

    openMuxer(fmt);

    return 0;
}

void TcpTsMediaCaster::close()
{
    TcpServer::stop();

    closeMuxer();
    m_format.clear();
}

bool TcpTsMediaCaster::isOpen()
{
    return TcpServer::isStarted();
}

void TcpTsMediaCaster::writePacket(uint8_t* data, int size, int64_t pts, int flags)
{
    MediaPacketPtr packet(new MediaPacket());
    packet->set(data, size);
    packet->flags = flags;
    packet->pts = pts;

    writeMediaPacket(packet);
}

void TcpTsMediaCaster::closeAll()
{
    TcpServer::closeAll();
}

void TcpTsMediaCaster::removeAllTarget()
{
    BasicTsMediaCaster::removeAllTarget();
    closeAll();
}

void TcpTsMediaCaster::writeMediaPacket(MediaPacketPtr& pkt)
{
    auto func = [&](evutil_socket_t s, TcpConnectionPtr& connection)
    {
        dispatchPacket(connection, pkt);
        return true;
    };

    m_connMap.forEach(func);
}

TcpConnectionPtr TcpTsMediaCaster::create(evutil_socket_t fd)
{
    fireEvent(CASTER_SESSION_CREATE);

    TcpMediaCasterConnection* conn = new TcpMediaCasterConnection();

    conn->onMediaFormat(m_format);

    return TcpConnectionPtr(conn);
}

void TcpTsMediaCaster::onClose(TcpConnectionPtr& conn)
{
    fireEvent(CASTER_SESSION_DESTROY);

}


void TcpTsMediaCaster::dispatchPacket(TcpConnectionPtr& connection, MediaPacketPtr& pkt)
{
    TcpMediaCasterConnection* casterConnection = dynamic_cast<TcpMediaCasterConnection*>(connection.get());
    casterConnection->onMediaPacket(pkt);
}



} /* namespace av */
